#!/usr/bin/env python
#-*-coding:utf-8-*-

# __init__.py is part of "lemon-py" (http://code.google.com/p/lemon-py/).
# Copyright (C) 2010  - JBC <JBC dot Develop at gmail dot com >

# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU Lesser General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

# Based on code:
#   - http://code.activestate.com/recipes/546512/
#   - http://code.activestate.com/recipes/474070/


################################################################################
# DOCS
################################################################################

"""singleinstance.py es una libreria que evita que una aplicacion mantenga
dos instancias de si mismas.

Uso <example_oo.py>:

    import singleinstance

    class MyApp(singleinstance.SingleInstance):

        def __init__(self):
            ...

        def run(self):
            print "run Forrest run!"
            while True: pass

    app = MyApp()

    # Los parametros para otros sistemas operativos simplemente no se usan
    # pero es recomendable darlos a todos para que esto funcione en todas las
    # plataformas

    app.setup(pid_path = "path/to/pid/file.pid, # Used in *nix
              mutex="Myapp") # used in windows

    if app.isrunning():
        print "already running"
        del app
    else:
        app.run()

uso:
    $ python ejemplo.py &
        run Forrest run!
    $ python ejemplo.py
        already running


Uso <example_func.py>:
    
    import singleinstance
    
    if not singleinstance.isrunning(pid_path = "path/to/pid/file.pid, 
                                    mutex_name="Myapp", mutex_key="AAAA006756"):
        foo() # run something
        
                            

"""

################################################################################
# META
################################################################################

__prj__ = "singleinstance.py (lemon-py)"
__version__ = "0.1"
__license__ = "GPL3"
__author__ = "JBC"
__since__ = "0.1"
__date__ = "2010-06-23"
__copyright__ = "%s %s Copyright (C) %s %s" % (__prj__, __version__,
                                               __date__, __author__)


################################################################################
# IMPORTS
################################################################################

import os

import core

# For use confortably from outside
from core import SingleInstanceBase
from core import SingleInstanceError


################################################################################
# CONSTANS
################################################################################

# OS Groups
PID_FILE_OSS = ("posix",)
WINDOWS_OSS = ("nt",)


################################################################################
# MULTI PLATFORM MAGIC
################################################################################

def _get_class(os_name):
    
    if os_name in PID_FILE_OSS:
        import pid_file_oss
        return pid_file_oss.SingleInstance
    
    elif os_name in WINDOWS_OSS:
        import windows_oss
        return windows_oss.SingleInstance
        
    import os_not_supported
    return os_not_supported.SingleInstance


################################################################################
# CLASS
################################################################################

# THE CLASS DINAMICALLY SELECTED
SingleInstance = _get_class(os.name)


################################################################################
# FUNCTIONS
################################################################################

def get_lock(**kwargs):
    """Return a lock instance"""

    lock = SingleInstance()
    try:
        lock.setup(**kwargs)
    except SingleInstanceError, err:
        if err.code == core.ERROR_OS_NOT_SUPORTED[1]:
            pass
        else:
            raise err
    return lock
    
    
################################################################################
# MAIN
################################################################################

if __name__ == "__main__":
    print __doc__
